package tau.pimpmyfreedb.GUI;

import java.io.File;
import java.util.LinkedList;

import org.eclipse.swt.SWT;
import org.eclipse.swt.browser.Browser;
import org.eclipse.swt.events.ControlAdapter;
import org.eclipse.swt.events.ControlEvent;
import org.eclipse.swt.events.DisposeEvent;
import org.eclipse.swt.events.DisposeListener;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.ModifyListener;
import org.eclipse.swt.events.MouseAdapter;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.layout.FormAttachment;
import org.eclipse.swt.layout.FormData;
import org.eclipse.swt.layout.FormLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Canvas;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.FileDialog;
import org.eclipse.swt.widgets.Group;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.List;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.swt.widgets.MenuItem;
import org.eclipse.swt.widgets.MessageBox;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;

import tau.pimpmyfreedb.common.types.MusicItem;
import tau.pimpmyfreedb.common.types.PagedSearchResult;
import tau.pimpmyfreedb.dal.DataFilter;
import tau.pimpmyfreedb.dal.DataType;
import tau.pimpmyfreedb.dal.IDataItem;
import tau.pimpmyfreedb.master.IPimpMaster;
import tau.pimpmyfreedb.master.SearchInfo;

/**
 * 
 * The main GUI window
 * 
 */
public class MainWindow {

    // data members

    private IPimpMaster master;
    private MusicItem[] searchResults;
    private IDataItem[] friends;
    private IDataItem[] likes;
    private LinkedList<SearchInfo> history;
    private int currentPage = 0;
    private int totalPages = 0;
    private boolean skipSearch = false;

    // other windows

    private WaitWindow waitWindow;

    // gui controls

    private Shell shell = null;
    private Text searchBox, itemDetails;
    private List resultsList, friendsList, likesList;
    private Group resultTitleGroup;
    private Label searchLabel, resultHint, lblPaging, videoTitle,
	    itemDetailsLabel;
    private Canvas facebookLogo, likeLogo;
    private Button btnPrevPage, btnNextPage, backButton;
    private Browser youtubeBrowser;
    private Image bgImage, tmpImage;
    private Menu contextMenu;
    private MenuItem contextPlay, contextEdit, contextDelete;
    private Combo categoryCombo;
    private Composite logoLabel;

    public MainWindow(IPimpMaster master) {
	this.master = master;
	this.history = new LinkedList<SearchInfo>();
	shell = CreateShell();
    }

    private Shell CreateShell() {

	// getting the shell
	final Shell shell = SWTUtil.getResizeableShell();
	shell.addDisposeListener(new DisposeListener() {

	    @Override
	    public void widgetDisposed(DisposeEvent arg0) {
		master.close();
	    }
	});

	// shell's layout
	FormLayout mainLayout = new FormLayout();
	mainLayout.marginHeight = 10;
	mainLayout.marginWidth = 10;
	mainLayout.spacing = 10;
	shell.setLayout(mainLayout);
	shell.setSize(1250, 780);
	shell.setMinimumSize(900, 650);

	// background
	bgImage = new Image(SWTUtil.getDisplay(),
		"images/snoop_dogg_wallpapers_pimp.jpg");
	shell.addControlListener(new ControlAdapter() {
	    public void controlResized(ControlEvent arg0) {
		tmpImage = new Image(SWTUtil.getDisplay(), shell
			.getClientArea());
		GC gc = new GC(tmpImage);
		gc.drawImage(bgImage, 0, 0, bgImage.getBounds().width,
			bgImage.getBounds().height, 0, 0,
			shell.getClientArea().width,
			shell.getClientArea().height);
		shell.setBackgroundImage(tmpImage);
		shell.setBackgroundMode(SWT.INHERIT_DEFAULT);
	    }
	});

	// create the different parts
	createMenu(shell);
	createSearchArea(shell);
	createFacebookArea(shell);
	createResultArea(shell);
	createYouTubeArea(shell);

	// set the layout
	setLayout(shell);

	return shell;
    }

    private void createMenu(Shell shell) {
	// create the upper bar.
	Menu menu = new Menu(shell, SWT.BAR);

	// create "File" header
	MenuItem fileHeader = new MenuItem(menu, SWT.CASCADE);
	fileHeader.setText("File");

	// Create the drop down menu below the "Series" bar.
	Menu fileMenu = new Menu(shell, SWT.DROP_DOWN);
	// add the drop down menu to the header
	fileHeader.setMenu(fileMenu);

	// Add "Exit" button
	MenuItem exitFileMenuB = new MenuItem(fileMenu, SWT.PUSH);
	exitFileMenuB.setText("Exit");
	exitFileMenuB.addSelectionListener(new SelectionAdapter() {
	    @Override
	    public void widgetSelected(SelectionEvent e) {
		master.close();
	    }
	});

	// create "Manage" header
	MenuItem manageHeader = new MenuItem(menu, SWT.CASCADE);
	manageHeader.setText("Manage");

	// Create the drop down menu below the "Manage" bar.
	Menu manageMenu = new Menu(shell, SWT.DROP_DOWN);
	// add the drop down menu to the header
	manageHeader.setMenu(manageMenu);

	// Add "Import" button
	MenuItem importManageMenuB = new MenuItem(manageMenu, SWT.PUSH);
	importManageMenuB.setText("Import");
	importManageMenuB.addSelectionListener(new SelectionAdapter() {
	    @Override
	    public void widgetSelected(SelectionEvent e) {
		master.importData();
	    }
	});

	// Add "Add Artist" button
	MenuItem addArtistManageMenuB = new MenuItem(manageMenu, SWT.PUSH);
	addArtistManageMenuB.setText("Add Artist");
	addArtistManageMenuB.addSelectionListener(new SelectionAdapter() {
	    @Override
	    public void widgetSelected(SelectionEvent e) {
		master.handleAddArtist();
	    }
	});

	// create "Help" header
	MenuItem helpHeader = new MenuItem(menu, SWT.CASCADE);
	helpHeader.setText("Help");

	// Create the drop down menu below the "Manage" bar.
	Menu helpMenu = new Menu(shell, SWT.DROP_DOWN);
	// add the drop down menu to the header
	helpHeader.setMenu(helpMenu);

	// Add "About" button
	MenuItem aboutHelpMenuB = new MenuItem(helpMenu, SWT.PUSH);
	aboutHelpMenuB.setText("About");
	aboutHelpMenuB.addSelectionListener(new SelectionAdapter() {
	    @Override
	    public void widgetSelected(SelectionEvent e) {
		about();
	    }
	});

	// Add the menu
	shell.setMenuBar(menu);
    }

    private void createSearchArea(Shell shell) {

	// search box
	searchBox = new Text(shell, SWT.BORDER);
	searchBox.setEditable(true);
	searchBox.setText("");
	searchBox.addModifyListener(new ModifyListener() {
	    @Override
	    public void modifyText(ModifyEvent arg0) {
		onSearchBoxModified();
	    }
	});

	// search label
	searchLabel = new Label(shell, SWT.NONE);
	searchLabel.setText("Search:");

	// category combo
	categoryCombo = new Combo(shell, SWT.READ_ONLY);
	categoryCombo.add("Album");
	categoryCombo.add("Artist");
	categoryCombo.add("Track");
	categoryCombo.select(1);
	categoryCombo.addSelectionListener(new SelectionAdapter() {
	    public void widgetSelected(SelectionEvent e) {
		onCategoryChanged();
	    }
	});

	// logo
	logoLabel = new Composite(shell, SWT.NONE);
	Image logoImage = new Image(SWTUtil.getDisplay(),
		"images/PimpMyFreeDBLogo.jpg");
	logoLabel.setBackgroundImage(logoImage);
    }

    private void createFacebookArea(Shell shell) {

	// facebook logo
	facebookLogo = new Canvas(shell, SWT.NONE);

	// "like" image
	likeLogo = new Canvas(shell, SWT.NONE);

	// friends list
	friendsList = new List(shell, SWT.BORDER | SWT.V_SCROLL);
	friendsList.addSelectionListener(new SelectionAdapter() {
	    @Override
	    public void widgetSelected(SelectionEvent arg0) {
		master.showLikes();
		super.widgetSelected(arg0);
	    }
	});

	// likes list
	likesList = new List(shell, SWT.BORDER | SWT.V_SCROLL);
	likesList.addSelectionListener(new SelectionAdapter() {
	    @Override
	    public void widgetSelected(SelectionEvent arg0) {
		master.searchCurrentLike();
		super.widgetSelected(arg0);
	    }
	});
    }

    private void createResultArea(Shell shell) {

	// result title group
	final Font resultTitleGroupFont = new Font(SWTUtil.getDisplay(),
		"Arial", 11, SWT.BOLD);

	resultTitleGroup = new Group(shell, SWT.NONE);
	resultTitleGroup.setText("Search Results:");
	resultTitleGroup.setFont(resultTitleGroupFont);
	resultTitleGroup.addDisposeListener(new DisposeListener() {
	    @Override
	    public void widgetDisposed(DisposeEvent arg0) {
		resultTitleGroupFont.dispose();
	    }
	});

	// back button
	backButton = new Button(resultTitleGroup, SWT.PUSH);
	backButton.setText("Back");
	backButton.addMouseListener(new MouseAdapter() {
	    @Override
	    public void mouseDown(MouseEvent arg0) {
		master.back();
		super.mouseDown(arg0);
	    }
	});

	// results hint
	final Font resultHintFont = new Font(SWTUtil.getDisplay(), "Arial", 10,
		SWT.ITALIC);

	resultHint = new Label(resultTitleGroup, SWT.NONE);
	resultHint.setText("type in a search phrase...");
	resultHint.setFont(resultHintFont);
	resultHint.addDisposeListener(new DisposeListener() {
	    @Override
	    public void widgetDisposed(DisposeEvent arg0) {
		resultHintFont.dispose();
	    }
	});

	// lblPage
	final Font lblPagingFont = new Font(SWTUtil.getDisplay(), "Arial", 10,
		SWT.NONE);

	lblPaging = new Label(resultTitleGroup, SWT.NONE);
	lblPaging.setAlignment(SWT.LEFT);
	lblPaging.setText("Results 0-0 of 0");
	lblPaging.setFont(resultTitleGroupFont);
	lblPaging.setFont(lblPagingFont);
	lblPaging.addDisposeListener(new DisposeListener() {

	    @Override
	    public void widgetDisposed(DisposeEvent arg0) {
		lblPagingFont.dispose();

	    }
	});

	// previous page button
	btnPrevPage = new Button(resultTitleGroup, SWT.NONE);
	btnPrevPage.setText("<");
	btnPrevPage.addSelectionListener(new SelectionAdapter() {

	    @Override
	    public void widgetSelected(SelectionEvent arg0) {
		changePage(-1);
	    }
	});

	// next page button
	btnNextPage = new Button(resultTitleGroup, SWT.NONE);
	btnNextPage.setText(">");
	btnNextPage.addSelectionListener(new SelectionAdapter() {

	    @Override
	    public void widgetSelected(SelectionEvent arg0) {
		changePage(+1);
	    }
	});

	// results list
	resultsList = new List(shell, SWT.BORDER | SWT.V_SCROLL);
	resultsList.addMouseListener(new MouseAdapter() {
	    public void mouseDoubleClick(MouseEvent arg0) {
		if (resultsList.getSelectionIndex() != -1) {
		    master.playOrShow();
		}
	    }
	});
	resultsList.addSelectionListener(new SelectionAdapter() {
	    @Override
	    public void widgetSelected(SelectionEvent arg0) {
		master.showItemDetails();
	    }
	});

	// results list's context menu
	contextMenu = new Menu(resultsList);
	contextPlay = new MenuItem(contextMenu, SWT.NONE);
	resultsList.addSelectionListener(new SelectionAdapter() {

	    @Override
	    public void widgetSelected(SelectionEvent arg0) {
		resultsList.setMenu(contextMenu);
		super.widgetSelected(arg0);
	    }
	});

	// "play" menu item
	contextPlay.setText("Play");
	contextPlay.addSelectionListener(new SelectionAdapter() {
	    public void widgetSelected(SelectionEvent arg0) {
		master.playOrShow();
	    }
	});

	// "edit" menu item
	contextEdit = new MenuItem(contextMenu, SWT.NONE);
	contextEdit.setText("Edit Item");
	contextEdit.addSelectionListener(new SelectionAdapter() {
	    public void widgetSelected(SelectionEvent e) {
		master.edit();
	    }
	});

	// "delete" menu item
	contextDelete = new MenuItem(contextMenu, SWT.NONE);
	contextDelete.setText("Delete Item");
	contextDelete.addSelectionListener(new SelectionAdapter() {

	    @Override
	    public void widgetSelected(SelectionEvent arg0) {
		master.deleteMusicItem();
		super.widgetSelected(arg0);
	    }
	});
    }

    private void createYouTubeArea(Shell shell) {

	final Font videoTitleFont = new Font(shell.getDisplay(), "Arial", 14,
		SWT.BOLD);

	// video title label
	videoTitle = new Label(shell, SWT.NONE);
	videoTitle.setText("You're watching - PimpMyFreeDB");
	videoTitle.setFont(videoTitleFont);
	// add dispose listener (Font must be disposed)
	videoTitle.addDisposeListener(new DisposeListener() {

	    @Override
	    public void widgetDisposed(DisposeEvent e) {
		videoTitleFont.dispose();
	    }
	});

	youtubeBrowser = new Browser(shell, SWT.BORDER);
	youtubeBrowser.setBackground(SWTUtil.getDisplay().getSystemColor(
		SWT.COLOR_TITLE_BACKGROUND_GRADIENT));
	youtubeBrowser
		.setUrl("http://nunation.com/wp-content/uploads/2010/04/Music-on-Youtube.png");

	// item details label
	itemDetailsLabel = new Label(shell, SWT.NONE);
	itemDetailsLabel.setText("Item Details:");

	// item details text area
	itemDetails = new Text(shell, SWT.WRAP | SWT.BORDER | SWT.V_SCROLL
		| SWT.READ_ONLY);
    }

    private void setLayout(Shell shell) {

	FormData formData;

	int firstRowTopOffset = 30;
	int firstRowBottomSpacing = 30;
	int searchBoxWidth = 500;
	int searchBoxHeight = 25;

	// search box
	formData = new FormData(searchBoxWidth, searchBoxHeight);
	formData.top = new FormAttachment(shell, firstRowTopOffset);
	formData.left = new FormAttachment(50, -(searchBoxWidth / 2));
	searchBox.setLayoutData(formData);

	// search label
	formData = new FormData(60, searchBoxHeight);
	formData.top = new FormAttachment(searchBox, -(searchBoxHeight / 2),
		SWT.CENTER);
	formData.right = new FormAttachment(searchBox);
	searchLabel.setLayoutData(formData);

	// category combo
	formData = new FormData();
	formData.top = new FormAttachment(shell, firstRowTopOffset);
	formData.left = new FormAttachment(searchBox);
	categoryCombo.setLayoutData(formData);

	// logo
	formData = new FormData(100, 100);
	formData.right = new FormAttachment(100);
	logoLabel.setLayoutData(formData);

	// facebook logo
	int facebookLogoWidth = 150;
	int facebookLogoHeight = 45;
	formData = new FormData(facebookLogoWidth, facebookLogoHeight);
	formData.top = new FormAttachment(searchBox, firstRowBottomSpacing);
	formData.left = new FormAttachment(friendsList,
		-(facebookLogoWidth / 2), SWT.CENTER);
	facebookLogo.setLayoutData(formData);

	// facebook logo picture
	tmpImage = new Image(SWTUtil.getDisplay(), facebookLogoWidth,
		facebookLogoHeight);
	Image fbTempPic = new Image(SWTUtil.getDisplay(),
		"images/facebook_logo.jpg");
	GC fbTempGC = new GC(tmpImage);
	fbTempGC.drawImage(fbTempPic, 0, 0, fbTempPic.getBounds().width,
		fbTempPic.getBounds().height, 0, 0, facebookLogoWidth,
		facebookLogoHeight);
	fbTempPic.dispose();
	fbTempGC.dispose();
	facebookLogo.setBackgroundImage(tmpImage);

	// "like" logo
	int likeLogoWidth = 110;
	int likeLogoHeight = 37;
	formData = new FormData(likeLogoWidth, likeLogoHeight);
	formData.top = new FormAttachment(facebookLogo, -(likeLogoHeight / 2),
		SWT.CENTER);
	formData.left = new FormAttachment(likesList, -(likeLogoWidth / 2),
		SWT.CENTER);
	likeLogo.setLayoutData(formData);

	// "like" logo picture
	tmpImage = new Image(SWTUtil.getDisplay(), likeLogoWidth,
		likeLogoHeight);
	fbTempPic = new Image(SWTUtil.getDisplay(),
		"images/Facebook-Like-Button-big.jpg");
	fbTempGC = new GC(tmpImage);
	fbTempGC.drawImage(fbTempPic, 0, 0, fbTempPic.getBounds().width,
		fbTempPic.getBounds().height, 0, 0, likeLogoWidth,
		likeLogoHeight);
	fbTempPic.dispose();
	fbTempGC.dispose();
	likeLogo.setBackgroundImage(tmpImage);

	// friends list
	formData = new FormData(150, 200);
	formData.top = new FormAttachment(facebookLogo);
	formData.bottom = new FormAttachment(100);
	friendsList.setLayoutData(formData);

	// likes list
	formData = new FormData(200, 200);
	formData.top = new FormAttachment(facebookLogo);
	formData.bottom = new FormAttachment(100);
	formData.left = new FormAttachment(friendsList);
	likesList.setLayoutData(formData);

	// results title group
	formData = new FormData();
	formData.top = new FormAttachment(searchBox, firstRowBottomSpacing);
	formData.left = new FormAttachment(likesList);
	formData.right = new FormAttachment(resultsList, 0, SWT.RIGHT);
	resultTitleGroup.setLayoutData(formData);

	FormLayout resultTitleGroupLayout = new FormLayout();
	resultTitleGroupLayout.marginWidth = 3;
	resultTitleGroupLayout.spacing = 3;
	resultTitleGroup.setLayout(resultTitleGroupLayout);

	// back button
	formData = new FormData(50, 35);
	formData.top = new FormAttachment(resultTitleGroup,
		-(backButton.getSize().y / 2) + 5, SWT.CENTER);
	formData.left = new FormAttachment(resultTitleGroup, 0, SWT.LEFT);
	backButton.setLayoutData(formData);

	// results hint
	formData = new FormData();
	formData.top = new FormAttachment(0);
	formData.left = new FormAttachment(backButton);
	formData.right = new FormAttachment(100);
	resultHint.setLayoutData(formData);

	// paging label
	formData = new FormData();
	formData.top = new FormAttachment(resultHint);
	formData.left = new FormAttachment(backButton);
	formData.right = new FormAttachment(btnPrevPage);
	lblPaging.setLayoutData(formData);

	// previous page button
	formData = new FormData(25, 25);
	formData.top = new FormAttachment(resultHint);
	formData.right = new FormAttachment(btnNextPage);
	btnPrevPage.setLayoutData(formData);

	// next page button
	formData = new FormData(25, 25);
	formData.top = new FormAttachment(resultHint);
	formData.right = new FormAttachment(100);
	btnNextPage.setLayoutData(formData);

	// results list
	formData = new FormData(330, 200);
	formData.top = new FormAttachment(resultTitleGroup);
	formData.bottom = new FormAttachment(100);
	formData.left = new FormAttachment(resultTitleGroup, 0, SWT.LEFT);
	resultsList.setLayoutData(formData);

	// video title
	formData = new FormData();
	formData.top = new FormAttachment(searchBox, firstRowBottomSpacing);
	formData.left = new FormAttachment(resultsList);
	formData.right = new FormAttachment(100);
	videoTitle.setLayoutData(formData);

	// youtube browser
	formData = new FormData(600, 300);
	formData.top = new FormAttachment(videoTitle);
	formData.bottom = new FormAttachment(itemDetailsLabel);
	formData.left = new FormAttachment(videoTitle, 0, SWT.LEFT);
	formData.right = new FormAttachment(100);
	youtubeBrowser.setLayoutData(formData);

	// item details label
	formData = new FormData();
	// formData.top = new FormAttachment(youtubeBrowser);
	formData.bottom = new FormAttachment(itemDetails);
	formData.left = new FormAttachment(videoTitle, 0, SWT.LEFT);
	formData.right = new FormAttachment(100);
	itemDetailsLabel.setLayoutData(formData);

	// item details box
	formData = new FormData(600, 200);
	// formData.top = new FormAttachment(itemDetailsLabel);
	formData.bottom = new FormAttachment(100);
	formData.left = new FormAttachment(videoTitle, 0, SWT.LEFT);
	formData.right = new FormAttachment(100);
	itemDetails.setLayoutData(formData);
    }

    // --- getters and setters --- //

    public Shell getShell() {
	return shell;
    }

    public String getSearchString() {
	return searchBox.getText();
    }

    public DataType getCategory() {
	return Enum.valueOf(DataType.class, categoryCombo.getText()
		.toUpperCase());
    }

    public MusicItem getSelectedItem() {
	if (resultsList.getSelectionIndex() != -1)
	    return searchResults[resultsList.getSelectionIndex()];
	else if (resultsList.getItemCount() != 0)
	    return searchResults[0];
	else
	    return null;
    }

    public IDataItem getSelectedFriend() {
	return friends[friendsList.getSelectionIndex()];
    }

    public IDataItem getSelectedLike() {
	return likes[likesList.getSelectionIndex()];
    }

    public SearchInfo getLastHistoryItem() {
	if (history.size() > 0)
	    return history.getLast();

	return null;
    }

    public int getCurrentPage() {
	return currentPage;
    }

    public void setSearchString(String str) {
	if (str != null) {
	    setSkipSearch();
	    searchBox.setText(str);
	}
    }

    public void setCategory(DataType category) {
	setSkipSearch();
	switch (category) {
	case ALBUM:
	    categoryCombo.select(0);
	    break;
	case ARTIST:
	    categoryCombo.select(1);
	    break;
	case TRACK:
	    categoryCombo.select(2);
	    break;
	default:
	    break;
	}

	updateCategoryDetails();
    }

    public void setFriends(IDataItem[] friends) {
	this.friends = friends;
	friendsList.removeAll();
	for (int i = 0; i < friends.length; i++)
	    friendsList.add(friends[i].getName());
    }

    public void setLikes(IDataItem[] likes) {
	this.likes = likes;
	likesList.removeAll();
	for (int i = 0; i < likes.length; i++)
	    likesList.add(likes[i].getName());
    }

    public void setSearchResult(PagedSearchResult<MusicItem[]> param) {
	resultsList.removeAll();
	resultsList.setMenu(null);
	for (int i = 0; i < param.getResult().length; i++)
	    resultsList.add(param.getResult()[i].getName());
	searchResults = param.getResult();
	handlePages(param.getCurrentResultsPage(), param.getTotalResultsCount());
    }

    private void setResultHint(String hint) {
	resultHint.setText(hint);
    }

    public void setResultTitle(SearchInfo se) {
	String title = "Showing ";
	boolean isEmptySearchString = false;
	if (se == null || se.getSearchString() == null
		|| se.getSearchString().isEmpty())
	    isEmptySearchString = true;
	if (isEmptySearchString)
	    title += "all ";
	switch (se.getSearchType()) {
	case ALBUM:
	    title += "Albums ";
	    break;
	case ARTIST:
	    title += "Artists ";
	    break;
	case TRACK:
	    title += "Tracks ";
	    break;
	default:
	    return;
	}
	if (!isEmptySearchString)
	    title += "for \"" + se.getSearchString() + "\"";

	resultTitleGroup.setText(title);
    }

    public void setBrowserURL(String url) {
	if (url == null)
	    SWTUtil.messageBox("can not found a video for that track");
	else
	    youtubeBrowser.setUrl(url);
    }

    public void setVideoTitle(String title) {
	videoTitle.setText(title);
    }

    public void setDetails(String desc) {
	itemDetails.setText(desc);
    }

    public void setSkipSearch() {
	skipSearch = true;
    }

    public void addHistoryItem(String name, DataType type, DataFilter filter) {
	history.add(new SearchInfo(name, type, filter));
    }

    public void removeLastHistoryItem() {
	if (history.size() > 0)
	    history.removeLast();
    }

    public void updateCategoryDetails() {
	// fix the context menu
	switch (getCategory()) {
	case TRACK:
	    contextPlay.setText("Play");
	    break;
	case ALBUM:
	    contextPlay.setText("Show Tracks");
	    break;
	case ARTIST:
	    contextPlay.setText("Show Albums");
	    break;
	default:
	    break;
	}

	// set the results title
	switch (getCategory()) {
	case TRACK:
	    setResultHint("double-click a Track to play");
	    break;
	case ALBUM:
	    setResultHint("double-click an Album to show Tracks");
	    break;
	case ARTIST:
	    setResultHint("double-click an Artist to show Albums");
	    break;
	default:
	    break;
	}
    }

    // --- popups & dialogs --- //

    public boolean confirmBox(String msg) {
	MessageBox confirmBox = new MessageBox(shell, SWT.ICON_QUESTION
		| SWT.OK | SWT.CANCEL);
	confirmBox.setMessage(msg);
	return confirmBox.open() == SWT.OK;
    }

    public WaitWindow openWaitWindow(String msg, boolean closeOnCancel) {
	waitWindow = new WaitWindow(shell, closeOnCancel);
	waitWindow.open(msg);
	return waitWindow;
    }

    public void closeWaitWindow() {
	waitWindow.close();
    }

    public String[] openImportDialog() {

	// create the file dialog
	FileDialog fd = new FileDialog(shell, SWT.MULTI);
	fd.setText("Select Archives");
	fd.setFilterPath("C:/");
	fd.setFilterExtensions(new String[] { "*.tar.bz2", "*.*" });
	shell.setEnabled(false);

	// open
	String fileName = fd.open();
	if (fileName != null) {
	    String filePath = fileName.substring(0,
		    fileName.lastIndexOf(File.separator) + 1);
	    String[] filePaths = new String[fd.getFileNames().length];
	    for (int i = 0; i < fd.getFileNames().length; i++) {
		filePaths[i] = filePath + fd.getFileNames()[i];
	    }
	    return filePaths;
	}
	return new String[0];
    }

    
    // --- private --- //

    private void onCategoryChanged() {
	updateCategoryDetails();
	this.currentPage = 0;
	if (skipSearch)
	    skipSearch = false;
	else
	    master.search();
    }

    private void onSearchBoxModified() {
	currentPage = 0;
	totalPages = 0;
	if (getSearchString() == null || getSearchString() == "")
	    resetTitleAndHint();
	if (skipSearch)
	    skipSearch = false;
	else
	    master.search();
    }

    private void resetTitleAndHint() {
	resultTitleGroup.setText("Search Results:");
	resultHint.setText("type in a search phrase...");
    }

    private void handlePages(int currentPage, int totalResultsCount) {
	this.currentPage = currentPage;
	int pageSize = DataFilter.DefaultPageSize;
	int firstResult = currentPage * pageSize + 1;
	int lastResult = Math.min((currentPage + 1) * pageSize,
		totalResultsCount);
	if (firstResult > totalResultsCount)
	    firstResult = totalResultsCount;
	lblPaging.setText(String.format("Results %d-%d of %d", firstResult,
		lastResult, totalResultsCount));
	this.totalPages = (totalResultsCount / pageSize)
		+ (totalResultsCount % pageSize > 0 ? 1 : 0);
	btnPrevPage.setEnabled(currentPage > 0);
	btnNextPage.setEnabled(currentPage < totalPages - 1);
    }

    protected void changePage(int delta) {
	currentPage += delta;
	if (currentPage < 0)
	    currentPage = 0;
	master.search();
    }
    
    private void about()
    {
	MessageBox about = new MessageBox(shell, SWT.ICON_INFORMATION);
	about.setText("PimpMyFreeDB");
	String msg = "Created by:\n\n" +
		"Alon Bar\t\tYonatan Erez\n" +
		"Oren Gafni\tAbir Yassin\n\n" +
		"As a final project in the course Database Systems\n" + 
		"by Tova Milo and Rubi Boim, Tel-Aviv University";
		
	about.setMessage(msg);
	about.open();
    }
}
